﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "GcmpUiBase.h"

class QObject;
namespace gcmp {
    class GCMP_UIBASE_EXPORT QtNewUtils {
    public:
        static bool isInChildQtThread();
        static bool doesAllowToNewAt(const wchar_t * pFile, const int line, const wchar_t * pFunction);
        static bool doesAllowToAccess(const QObject *);
    };
}

//
// Create a QWidget object.
#define NEW_AS_QT_QWIDGET(TYPE, ...)                                                        \
    ([=](const wchar_t * pFile, const int line, const wchar_t * pFunction)->TYPE* {         \
        if (!gcmp::QtNewUtils::doesAllowToNewAt(pFile, line, pFunction))                    \
            return nullptr;                                                                 \
        static_assert(std::is_base_of<QWidget, TYPE>::value, "Only QWidget is supported!"); \
        TYPE * pQtWgt = new TYPE(__VA_ARGS__);                                              \
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(nullptr != pQtWgt,                               \
            L"Null pQtWgt!", L"fangkunfk", L"2023-08-15");                                  \
        return pQtWgt;                                                                      \
    }(_CRT_WIDE(__FILE__), __LINE__, _CRT_WIDE(__FUNCTION__)))

//
// Create a child QWidget object.
#define NEW_AS_QT_CHILD_QWIDGET(TYPE, ...)                                                  \
    ([=](const wchar_t * pFile, const int line, const wchar_t * pFunction)->TYPE* {         \
        if (!gcmp::QtNewUtils::doesAllowToNewAt(pFile, line, pFunction))                    \
            return nullptr;                                                                 \
        static_assert(std::is_base_of<QWidget, TYPE>::value, "Only QWidget is supported!"); \
        TYPE * pQtWgt = new TYPE(__VA_ARGS__);                                              \
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(                                                 \
            nullptr != pQtWgt && nullptr != pQtWgt->parent(),                               \
            L"Null pQtWgt or its parent!", L"fangkunfk", L"2023-08-15");                    \
        return pQtWgt;                                                                      \
    }(_CRT_WIDE(__FILE__), __LINE__, _CRT_WIDE(__FUNCTION__)))

//
// Can create a QWidget object.
#define CAN_NEW_AS_QT_QWIDGET \
      gcmp::QtNewUtils::doesAllowToNewAt(_CRT_WIDE(__FILE__), __LINE__, _CRT_WIDE(__FUNCTION__))

//
// Cannot create a QWidget object.
#define CANNOT_NEW_AS_QT_QWIDGET \
    (!gcmp::QtNewUtils::doesAllowToNewAt(_CRT_WIDE(__FILE__), __LINE__, _CRT_WIDE(__FUNCTION__)))